package com.xiangxiao.rpan.storage.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.xiangxiao.rpan.storage.constant.ResponseCode;
import com.xiangxiao.rpan.storage.constant.ResponseMessage;
import com.xiangxiao.rpan.storage.dao.StorageSourceConfigMapper;
import com.xiangxiao.rpan.storage.dto.StorageSourceAllParamDTO;
import com.xiangxiao.rpan.storage.entity.StorageSourceConfig;
import com.xiangxiao.rpan.storage.entity.StorageSourceParamDef;
import com.xiangxiao.rpan.storage.enums.StorageTypeEnum;
import com.xiangxiao.rpan.storage.exception.StorageExcetion;
import com.xiangxiao.rpan.storage.factory.StorageSourceContext;
import com.xiangxiao.rpan.storage.service.StorageSourceConfigService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @auther xiangxiao
 * @email 573768011@qq.com
 * @data 2023/10/27 15:28
 */
@Service
@Slf4j
public class StorageSourceConfigServiceImpl implements StorageSourceConfigService {
  private static Logger logger = LoggerFactory.getLogger(StorageSourceServiceImpl.class);
  @Resource
  private StorageSourceConfigMapper storageSourceConfigMapper;
  @Override
  public List<StorageSourceConfig> toStorageSourceConfigList(Integer storageId, StorageTypeEnum storageType, StorageSourceAllParamDTO storageSourceAllParam) {
    List<StorageSourceConfig> result = new ArrayList<>();
    // 先根据storageType从StorageSourceContext中获取该存储源类型需要的参数列表
    List<StorageSourceParamDef> storageSourceParamList = StorageSourceContext.getStorageSourceParamListByType(storageType);
    // 遍历参数列表, 将参数转换成存储源参数对象
    for (StorageSourceParamDef storageSourceParam : storageSourceParamList) {
      // 根据字段名称获取字段值
      Object fieldValue = ReflectUtil.getFieldValue(storageSourceAllParam, storageSourceParam.getKey());
      String fieldStrValue = Convert.toStr(fieldValue);

      // 校验是否必填, 如果不符合则抛出异常
      boolean paramRequired = storageSourceParam.isRequired();
      if (paramRequired && StrUtil.isEmpty(fieldStrValue)) {
        String errMsg = StrUtil.format("参数「{}」不能为空", storageSourceParam.getName());
        logger.error(errMsg, storageSourceParam.getName());
        throw new StorageExcetion(ResponseMessage.STORAGE_SOURCE_INIT_STORAGE_PARAM_FIELD_FAIL, ResponseCode.STORAGE_SOURCE_INIT_STORAGE_PARAM_FIELD_FAIL);
      }

      // 校验如果有默认值，则填充默认值
      String paramDefaultValue = storageSourceParam.getDefaultValue();
      if (StrUtil.isNotEmpty(paramDefaultValue) && StrUtil.isEmpty(fieldStrValue)) {
        fieldStrValue = paramDefaultValue;
      }

      // 添加到结果列表
      StorageSourceConfig storageSourceConfig = new StorageSourceConfig();
      storageSourceConfig.setTitle(storageSourceParam.getName());
      storageSourceConfig.setName(storageSourceParam.getKey());
      storageSourceConfig.setValue(fieldStrValue);
      storageSourceConfig.setType(storageType);
      storageSourceConfig.setStorageId(storageId);
      result.add(storageSourceConfig);
    }
    return result;
  }

  @Override
  public void saveBatch(Integer storageId, Collection<StorageSourceConfig> configList) {
    this.deleteByStorageId(storageId);

    log.info("更新存储源 ID 为 {} 的参数配置 {} 条", storageId, configList.size());

    configList.forEach(storageSourceConfig -> {
      storageSourceConfig.setStorageId(storageId);
      storageSourceConfigMapper.insertSingle(storageSourceConfig);

      if (log.isDebugEnabled()) {
        log.debug("新增存储源参数配置, 存储源 ID: {}, 存储源类型: {}, 参数名: {}",
            storageSourceConfig.getStorageId(), storageSourceConfig.getType().getDescription(),
            storageSourceConfig.getName());
      }
    });
  }

  @Override
  public int deleteByStorageId(Integer storageId) {
    int deleteSize = storageSourceConfigMapper.deleteByStorageId(storageId);
    return deleteSize;
  }
}
